package vip.aster.generator.config;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import vip.aster.generator.config.query.*;
import vip.aster.generator.entity.GenDataSource;
import vip.aster.generator.utils.DbUtils;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * 代码生成器 数据源
 *
 * @author Aster
 * @since 2024/2/23 15:35
 */
@Data
@Slf4j
public class DataSourceConfig {
    /**
     * 数据源ID
     */
    private String id;
    /**
     * 数据库类型
     */
    private DbType dbType;
    /**
     * 数据库URL
     */
    private String connUrl;
    /**
     * 用户名
     */
    private String username;
    /**
     * 密码
     */
    private String password;

    private AbstractQuery dbQuery;

    private Connection connection;

    public DataSourceConfig(GenDataSource entity) {
        this.id = entity.getId();
        this.dbType = DbType.getValue(entity.getDbType());
        this.connUrl = entity.getConnUrl();
        this.username = entity.getUsername();
        this.password = entity.getPassword();
        this.dbQuery = getDbQueryByType(this.dbType);

        try {
            this.connection = DbUtils.getConnection(this);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public DataSourceConfig(Connection connection) throws SQLException {
        this.id = null;
        this.dbType = DbType.getValue(connection.getMetaData().getDatabaseProductName());

        this.dbQuery = getDbQueryByType(this.dbType);

        this.connection = connection;
    }

    private AbstractQuery getDbQueryByType(DbType type) {
        AbstractQuery abstractQuery = null;
        if (type == DbType.MySQL) {
            abstractQuery = new MySqlQuery();
        } else if (type == DbType.Oracle) {
            abstractQuery = new OracleQuery();
        } else if (type == DbType.PostgreSQL) {
            abstractQuery = new PostgreSqlQuery();
        } else if (type == DbType.SQLServer) {
            abstractQuery = new SQLServerQuery();
        } else if (type == DbType.DM) {
            abstractQuery = new DmQuery();
        } else if (type == DbType.Clickhouse) {
            abstractQuery = new ClickHouseQuery();
        }else if (type == DbType.KingBase) {
            abstractQuery = new KingBaseSqlQuery();
        }
        return abstractQuery;
    }
}
